package com.tanhua.manage.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.mail.util.MailSSLSocketFactory;
import com.tanhua.manage.expection.BusinessException;
import com.tanhua.manage.mapper.AdminMapper;
import com.tanhua.manage.pojo.Admin;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;


import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class SystemService {
    @Autowired
    AdminMapper adminMapper;
    @Value("${jwt.secret}")
    private String secret;
    @Autowired
    private RedisTemplate<String,String>redisTemplate;


    public String login(Map<String, String> param) {
        //获取参数
        String username= param.get("username");
        String password = DigestUtils.md5Hex(param.get("password"));
        System.out.println("password = " + password);
        //账号输入非空校验
        if (StringUtils.isEmpty(username)){
            return null;
        }
        if (StringUtils.isEmpty(password)){
            return null;
        }
        //验证码
        String uuid = param.get("uuid");
        String verificationCode = param.get("verificationCode");
        if (StringUtils.isEmpty(verificationCode)){
            return null;
        }
        //验证这个账号今日是否登录次数过多
        String count = redisTemplate.opsForValue().get("erroruser" + username);
        System.out.println("count = " + count);
        if (StringUtils.equals(count,"3")){
            //throw  new BusinessException("这个账号今日封了,明天再来试试");
            System.out.println("这个账号今日封了,明天再来试试哦geigei");
            return null;
        }
        //校验账号
        QueryWrapper<Admin>wrapper =new QueryWrapper<>();
        wrapper.eq("username",username);
        wrapper.eq("password",password);
        Admin admin = adminMapper.selectOne(wrapper);

        if (null==admin){
            //设置错误次数
            String usernameKey="erroruser"+username;
          count = redisTemplate.opsForValue().increment(usernameKey).toString();
            redisTemplate.opsForValue().set(usernameKey,count,Duration.ofDays(1));
           // throw  new BusinessException("账号不对哦亲");
            try {
                sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("账号不对哦亲");
            return null;
        }
        redisTemplate.delete("erroruser"+username);
        //检验验证码
        String codeKey="CACHE_CODE_PREFIX" + uuid;
        String value = redisTemplate.opsForValue().get(codeKey);
        if (!StringUtils.equalsIgnoreCase(value,verificationCode)){
         //  throw  new BusinessException("验证码不对哦亲");
            System.out.println("验证码不对哦亲");

        }


        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("username", admin.getUsername());
        claims.put("id", admin.getUid());

        // 生成token
        String token = Jwts.builder()
                .setClaims(claims) //设置响应数据体
                .signWith(io.jsonwebtoken.SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .compact();

        try {
            // 将token存储到redis中
            String redisTokenKey = "CACHE_KEY_TOKEN" + token;

            //将密码设置为null，不参与序列化
            admin.setPassword(null);
            ObjectMapper mapper = new ObjectMapper();
            String redisTokenValue = mapper.writeValueAsString(admin);
            this.redisTemplate.opsForValue().set(redisTokenKey, redisTokenValue, Duration.ofDays(7));
            return token;
        } catch (Exception e) {
            log.error("存储token出错", e);
            return null;
        }
    }

    /*保存验证码
    * saveVerification
    * @param [uuid, code]
    */public void saveVerification(String uuid, String code) {
        //将验证码存入redis,设置有效时间为10分钟
        String key= "CACHE_CODE_PREFIX" + uuid;
        this.redisTemplate.opsForValue().set(key,code, Duration.ofMinutes(10));
    }

    public Admin find(String token) {
        //从redis中获取token
        String redisTokenKey = "CACHE_KEY_TOKEN" + token;
        String data = redisTemplate.opsForValue().get(redisTokenKey);
        //设置过期时间
        redisTemplate.expire(redisTokenKey,50, TimeUnit.MINUTES);
        //反序列化
        ObjectMapper mapper =new ObjectMapper();
        try {
            Admin admin = mapper.readValue(data, Admin.class);
            return admin;
        } catch (IOException e) {
            e.printStackTrace();
        }


        return null;
    }

    public void removeToken(String token) {
        String redisTokenKey = "CACHE_KEY_TOKEN" + token;
        redisTemplate.delete(redisTokenKey);
    }



    public  void sendEmail() throws Exception {
        Properties prop = new Properties();
        // 开启debug调试，以便在控制台查看
        prop.setProperty("mail.debug", "true");
        // 设置邮件服务器主机名
        prop.setProperty("mail.host", "smtp.qq.com");
        // 发送服务器需要身份验证
        prop.setProperty("mail.smtp.auth", "true");
        // 发送邮件协议名称
        prop.setProperty("mail.transport.protocol", "smtp");
        // 开启SSL加密，否则会失败
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        prop.put("mail.smtp.ssl.enable", "true");
        prop.put("mail.smtp.ssl.socketFactory", sf);
        // 创建session
        Session session = Session.getInstance(prop);
        // 通过session得到transport对象
        Transport ts = session.getTransport();
        // 连接邮件服务器：邮箱类型，帐号，POP3/SMTP协议授权码 163使用：smtp.163.com
        ts.connect("smtp.qq.com", "1317030850@qq.com", "ourgetyxcbywgfde");
        // 创建邮件
        Message message = createSimpleMail(session);
        // 发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        ts.close();
    }

    /**
     * @Method: createSimpleMail
     * @Description: 创建一封只包含文本的邮件
     */

    public static MimeMessage createSimpleMail(Session session) throws Exception {


        // 创建邮件对象
        MimeMessage message = new MimeMessage(session);
        // 指明邮件的发件人
        message.setFrom(new InternetAddress("1317030850@qq.com"));
        // 指明邮件的收件人，发件人和收件人如果是一样的，那就是自己给自己发
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("1079318000@qq.com"));
        // 邮件的标题
        message.setSubject("完犊子,账号出现风险了哦");
        // 邮件的文本内容
        message.setContent("你的探花后台账号< admin >出现登录密码次数错误过多的风险:"+",请及时排查.否则将会冻结"+"www.baidu.com", "text/html;charset=UTF-8");

        // 返回创建好的邮件对象
        return message;
    }
}
